
/// MLSDEFORMER source code
/// by Alvaro Cuno, LCG-COPPE-UFRJ 
/// bugs? email-me: alvaroecp@gmail.com
/// January, 2007

#ifndef __CONSTRAINTS_H_
#define __CONSTRAINTS_H_

#include "../typedefs.h"
#include <vector>


/// This class represents a set of constraints defined by
/// an array of positions (x,y,z). If the constraint is associated
/// to one geometric object (vertex, edge, etc.) you can attach its ID
class Constraints {
   
public:
   
   Constraints();
   ~Constraints();
   
   const Constraints& operator=(const Constraints &c);
   
   /// Inserts a new constraint point at the end
   void push_back(const Point3 &p);
   void push_back(const Point3 &p, int id);
   
   /// Returns the number of constraints
   unsigned int size() const { return positions.size(); }
   
   /// Reserves memory for n constraints
   void reserve(unsigned int n);
   
   /// Delete the i-th constraint
   ///@param i index of the constraint
   void erase(unsigned int i);
   
   /// Clear the constraints
   void clear() { ids.clear(); positions.clear(); }
   
   bool empty() { return positions.empty(); }
   
   // ACCESSORS FUNCTIONS
   /// Returns a float pointer poinitng the deformed position of the i-th constraint
   ///@param i index of the constraint
   ///@return a constant float pointer
   const Number* getPositionPointer(unsigned int i) const;
   
   /// Returns the initial positions of the i-th constraint
   ///@param i index of the constraint
   ///@return the deformed position
   Point3 getPosition(unsigned int i) const;
   
   /// Sets the deformed positions of the i-th constraint with a new value
   ///@param i index of the constraint
   ///@param p the new position
   void setPosition(unsigned int i, const Point3 &p);
   
   // TRANSFORMATIONS FUNCTIONS
   
   /// Applies the affine transformation on all constraints
   ///@param m the matrix transformation
   void transform(Number m[]);
   
   /// Rotates the constraints using an axis-angle definition
   ///@param o the rotation center
   ///@param u the unitary rotation vector
   ///@param angle the rotation angle in radians
   void rotate(const Point3 &o, const Vector3 &u, Number angle);
   
   /// Translates the constraints 
   ///@param t the translation vector
   void translate(const Vector3 &t);
   
   /// Applies an affine transformation on position of the k-th constraint
   ///@param k index of the constraint
   ///@param m the matrix transformation
   void transform(unsigned int k, Number m[]);
   
   /// Rotates the position of k-th constraint using an axis-angle definition
   ///@param k index of the constraint
   ///@param o the rotation center
   ///@param u the unitary rotation vector
   ///@param angle the rotation angle in radians
   void rotate(unsigned int k, const Point3 &o, const Vector3 &u, Number angle);
   
   /// Translates the position of the k-th constraint 
   ///@param t the translation vector
   void translate(unsigned int k, const Vector3 &t);
   
   /// Applies the transformations on the position of the constraint's group g
   ///@param g array de index of constraints
   ///@param m the matrix transformation
   void transform(const std::vector<unsigned int> &g, float m[]);
   
   /// Rotates the positions of a group of constraints using an axis-angle definition
   ///@param g array with index of the constraints
   ///@param o the rotation center
   ///@param u the unitary rotation vector
   ///@param angle the rotation angle in radians
   void rotate(const std::vector<unsigned int> &g, const Point3 &o, const Vector3 &u, Number angle);
   
   /// Translates the deformed positions of a group of constraints
   ///@param g array with index of the constraints
   ///@param t the translation vector
   void translate(const std::vector<unsigned int> &g, const Vector3 &t);
   
//~ private:
   
   std::vector<Point3>    positions;    //< positions of control points 
   std::vector<int>       ids;          //< id of the geometric object associated with the constraint 
};

#endif
